Go言語のマルチクラウド開発ライブラリ「Go Cloud」のAWS対応を試す
はじめに
AWS事業本部プロダクト開発グループのshoito(しょいと)です。
Go言語のマルチクラウド開発のためのライブラリとツールである「Go Cloud」のAWS対応を試してみました。
なお、2018年9月10日時点では、プロジェクトのステータスはまだアルファであり、APIには破壊的変更がありえるので、プロダクションには適していません。
https://github.com/google/go-cloud#project-status
検証環境
- macOS High Sierra 10.13.2
- Docker Community Edition 18.06.1-ce-mac73 (26764)
- Terraform v0.11.8
- Go 1.11 darwin/amd64
- AWS CLI 1.16.1
- Google Cloud SDK 215.0.0
Go Cloudとは
Go Cloudは、Go言語でポータブルなクラウドアプリケーションが開発できるように、クラウドプロバイダ間で使用頻度の高いサービスの汎用APIの開発を目指しています。 Go Cloudは、そのためのライブラリやツールを提供してくれます。
具体的には、S3のようなオブジェクトストレージ、RDB(MySQL)、リクエストログ、トレースのための汎用APIなどです。 2018年9月7日時点では、AWSとGCPの一部サービスに対応しています。
Package cloud contains a library and tools for open cloud development in Go.
https://godoc.org/github.com/google/go-cloud
Go Cloudのインストール
https://github.com/google/go-cloud のREADMEを参考に進めます。
まず、以下のように go-cloud
と wire
を go get
します。
$ go get github.com/google/go-cloud $ go get github.com/google/go-cloud/wire/cmd/wire
wire
はコードジェネレータであり、使用するクラウドプロバイダのSDKのみインポートするコードを生成します。
samples/guestbook
にある wire_gen.go
が生成されるコード例です。
コードの詳細はThe Go Blogの Portable Cloud Programming with Go Cloud が参考になります。
今回デプロイしたサンプル
今回は samples/guestbook
をビルドし、AWSとGCPの環境にデプロイしてみました。
https://github.com/google/go-cloud/tree/master/samples/guestbook
samples/guestbook
はAWS、GCP、ローカルの環境で実行できるゲストブックアプリケーションです。
google/go-cloud
リポジトリでは、サンプルアプリケーションとして、 samples/tutorial
、samples/guestbook
、samples/wire
を提供しています。
サンプルのビルド&デプロイのための前提条件
Go、Go Cloud、Wire以外には、以下のインストールが必要です。
- Docker
- Terraform
- AWS CLI(AWSにデプロイする場合)
- Google Cloud SDK(GCPにデプロイする場合)
まずはローカル環境で動作確認
samples/guestbook
のREADMEを参考にローカル環境で動作確認をします。
$ cd ~/go/src/github.com/google/go-cloud/samples/guestbook $ GO111MODULE=on go build
Go 1.11から試験的に導入されているModulesにより、go buildを実行する際に、自動的に依存ライブラリをダウンロードしてビルドしてくれます。
ビルド後は、ローカルでMySQLサーバコンテナを起動します。
$ GO111MODULE=on go run localdb/main.go
次に別のターミナルでゲストブックのサーバプログラムを起動します。
$ echo 'Hello, World!' > motd.txt $ ./guestbook -env=local -bucket=blobs -motd_var=motd.txt
これでローカルで起動したので http://localhost:8080/
にブラウザからアクセスすると、ゲストブックアプリケーションが表示されます。
なお、 motd.txt
は管理者用のメッセージとして使用されています。
AWS環境にデプロイして試してみる
次に、今回の目的であるAWS環境へのデプロイを試します。 こちらもローカル環境で試した際と同様にREADMEの手順を参考にします。
まずはAWS CLIとSSHの下準備。 既に他で実施済みであれば不要です。
$ aws configure $ ssh-add
サンプルではAWS MarketplaceにあるDebian提供のAMIにデプロイするため、AMD64ビットベースのLinux向けにビルドします。
$ GO111MODULE=on GOOS=linux GOARCH=amd64 go build
次に、terraformでAWS環境にデプロイするのですが、ここではREADMEとは別に terraform apply
時のリージョンを region=us-west-1
(米国西部 (北カリフォルニア))から region=ap-northeast-1
(東京)へ変更しています。
ssh_public_key
は後でEC2インスタンスにssh接続し、サーバプログラムを起動するために必要となります。
$ cd aws $ terraform init $ terraform apply -var region=ap-northeast-1 -var ssh_public_key="$(cat ~/.ssh/id_rsa.pub)"
AWS Marketplaceで Debian GNU/Linux 9 (Stretch)
の利用に同意していない場合、以下のようなエラーが発生し、デプロイに失敗してしまうので、メッセージに記載のURLにブラウザからアクセスして同意後、上記の terraform apply
を再度実行します。
* aws_instance.guestbook: 1 error(s) occurred: * aws_instance.guestbook: Error launching source instance: OptInRequired: In order to use this AWS Marketplace product you need to accept terms and subscribe. To do so please visit https://aws.amazon.com/marketplace/pp?sku=55q52qvgjfpdj2fpfy9mb1lo4 status code: 401, request id: XXXX-XXXX-XXXX-XXXX-XXXX Terraform does not automatically rollback in the face of errors. Instead, your Terraform state file has been partially updated with any resources that successfully completed. Please address the error above and apply again to incrementally change your infrastructure.
terraform apply
によるデプロイが完了すると、以下のように構築されたS3バケットやRDS、EC2インスタンスの情報などが出力されます。
Apply complete! Resources: 13 added, 0 changed, 0 destroyed. Outputs: bucket = guestbook[timestamp] database_host = guestbook[timestamp][redacted].[region].rds.amazonaws.com database_root_password = <sensitive> instance_host = [redacted] paramstore_var = /guestbook/motd region = [region]
次にinstance_host(EC2)に接続して、サーバプログラムを実行します。
-bucket
, -db_host
は terraform apply
の出力結果で適宜置き換えてください。
local$ ssh "admin@$( terraform output instance_host )" server$ AWS_REGION=ap-northeast-1 ./guestbook -env=aws \ -bucket=guestbook[timestamp] \ -db_host=guestbook[timestamp][redacted].[region].rds.amazonaws.com \ -motd_var=/guestbook/motd
これでデプロイ&起動が完了したので、ブラウザで http://INSTANCE_HOST:8080/
を開きます。
しかし、ローカル環境と同様にゲストブックアプリケーションが開くと期待していたのですが、手元で試したところ正常に動きませんでした。
サーバのログを見ると以下のようなログが出力されており、必要なDBユーザーが作られていませんでした。
2018/09/07 14:48:43 main page SQL error: Error 1045: Access denied for user 'guestbook'@'' (using password: YES)
samples/guestbook/roles.sql
にユーザー作成用のSQLがあるので、そちらを実行すると、正常にゲストブックアプリケーションが動きました。
最後に
今回はGo CloudのAWS対応を samples/guestbook
を実際にビルド&デプロイして確認しました。
samples/guestbook/main.go
を見ると分かるのですが、AWS環境依存のコードはありません。
Go Cloudが aws-sdk-go
のAPIをラップし、汎用APIを提供することでクラウド環境に依存しない方法で記述できます。
GCP環境へのデプロイもAWS環境と同様にREADMEを参考に試したので、別の機会にまとめます。
AWSとGCPで、それぞれ多くのサービスを提供しているので、どこまで汎用APIを提供できるのか、またAzureなど他のクラウド環境への対応がどうなっていくのか、Go Cloudの動きはウォッチしておこうと思います。
参考資料
- Portable Cloud Programming with Go Cloud: https://blog.golang.org/go-cloud
- Go言語チームとGoogleが「Go Cloud」プロジェクト発表。同一コードでAWSやGoogle Cloudなどに対応できるポータブルなクラウドアプリの実現へ: https://www.publickey1.jp/blog/18/gogooglego_cloudawsgoogle_cloud.html
- Guestbook Sample: https://github.com/google/go-cloud/tree/master/samples/guestbook